<?php
/**
 * Created by PhpStorm.
 * User: DongYao
 * Date: 2017/12/17
 * Time: 上午11:55
 */

namespace App\Observers;

use App\Jobs\GiveUserScoreNotice;
use App\Support\Facades\OperationLog;
use App\Tables\User;
use App\Tables\UserScoreTransferRecord;
use App\Exceptions\OperationException;
use Illuminate\Database\QueryException;
use Throwable;
use Log;
use DB;

class UserObserver
{
    public function created(User $user)
    {
        // 给邀请者赠送积分
        if (!empty($user->invite_code)) {
            $this->inviteGiveScore($user->invite_code, $user);
        }
    }

    /**
     * 注册用户成功后，给邀请者赠送积分
     * @param $invite_code 邀请者的邀请码
     * @param $invitee 被邀请者
     * @return \Illuminate\Http\JsonResponse
     */
    private function inviteGiveScore($invite_code, $invitee)
    {
        $invite_config = config('system.user_invite', []);

        Log::debug('开始进行邀请注册赠送积分处理', [$invite_config]);

        /**
         * 若开启了邀请注册功能则处理对应的业务逻辑
         * 1. 赠送积分
         */
        if (isset($invite_config['status']) && $invite_config['status'] === true) {
            /*
             * 判断邀请注册赠送积分的数量是否正确
             */
            if (isset($invite_config['give_score_num']) && intval($invite_config['give_score_num']) > 0) {
                $give_score_num = intval($invite_config['give_score_num']);

                /**
                 * 查询邀请者是否存在
                 */
                DB::beginTransaction();
                try {
                    $mobile = base_convert($invite_code, 32, 10);

                    $inviter = User::where('mobile', $mobile)->lockForUpdate()->first();
                    if (empty($inviter)) {
                        throw new OperationException('邀请新用户赠送积分-用户不存在', [$inviter->id, $give_score_num]);
                    }

                    $inviter->score = bcadd($inviter->score, $give_score_num, 0);
                    $res = $inviter->save();
                    if (!$res) {
                        throw new OperationException('邀请新用户赠送积分-更新用户积分失败', [$inviter->id, $inviter->name, $give_score_num]);
                    }

                    /**
                     * 增加充值赠送积分数量记录
                     */
                    $inviter_score_record = new UserScoreTransferRecord();
                    $inviter_score_record->user_id = $inviter->id;
                    $inviter_score_record->order_sn =  'IUG' . $inviter->id . date('YmdHis');;
                    $inviter_score_record->type = 'invite_user_give';
                    $inviter_score_record->score = $give_score_num;
                    $inviter_score_record->total_score = $inviter->score;
                    $res = $inviter_score_record->save();
                    if ($res === false) {
                        throw new OperationException('邀请新用户赠送积分-增加赠送积分记录失败', [$inviter->id, $inviter->name, $give_score_num]);
                    }
                    DB::commit();

                    // 记录操作日志
                    $log_message = "【{$inviter->name}】邀请【{$invitee->name}】注册成功，积分账户增加了{$give_score_num}个积分";
                    OperationLog::info('邀请新用户赠送积分', $log_message);

                    // 积分赠送成功后给用户发送通知
                    dispatch(new GiveUserScoreNotice($give_score_num, $inviter));
                } catch (OperationException $exception) {
                    DB::rollBack();
                } catch (QueryException $exception) {
                    Log::debug('邀请注册赠送积分处理失败', [$exception->getMessage(), $exception->getFile(), $exception->getLine()]);
                    DB::rollBack();
                } catch (Throwable $exception) {
                    Log::debug('邀请注册赠送积分处理失败', [$exception->getMessage(), $exception->getFile(), $exception->getLine()]);
                    DB::rollBack();
                }
            }
        }
    }
}
